package ng;

import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.io.IOException;
import java.util.ArrayList;

import lib.Config;
import ng.graphics.Camera;
import ng.lib.Utils;
import ng.lib.Vector2D;
import ng.map.Map;
import ng.map.MapObject;
import ng.map.MapObjectDynamic;
import ng.map.elements.objects.BlackHole;
import ng.map.elements.objects.Laser;
import ng.map.elements.objects.Rocket;
import ng.map.elements.objects.Spacecraft;
import ng.map.tiles.MapTile;
import ng.map.tiles.Wall;

public class Game implements Computable, Paintable {

	private final Map map;
	private final ArrayList<Camera> cameras = new ArrayList<Camera>();
	private KeyAdapter keyAdabter;
	private int height, width;

	public KeyAdapter getKeyAdabter() {
		return keyAdabter;
	}

	public Game(int w, int h) {
		this.height = h;
		this.width = w;
		this.map = new Map(Config.xRes, Config.yRes);

		try {
			this.map.setBackgroundImage(Utils
					.imageLodaer("data/textures/space/space.png"));
		} catch (IOException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}

		Camera cam1 = new Camera(map, new Rectangle(0, 0, this.width,
				this.height));

		// this.cam1.setZoom(0.25);
		Camera cam2 = new Camera(map, new Rectangle(20, 20, this.width / 2,
				this.height / 2));

		Camera cam3 = new Camera(map, new Rectangle(this.width / 2, 0,
				this.width / 2, this.height));
		// this.cam3.setZoomSpeed(0.001);
		// this.cam3.setZoom(2);
		// this.cam3 = new Camera(map, new Rectangle(0,500,1024,268), new
		// Vector2D(100,100));
		// this.cam2.setZoom(0.05);
		// this.cam4 = new Camera(map, new Rectangle(200,200,800,600));

		final MapObjectDynamic o1 = new Spacecraft(new Vector2D(100, 100));
		final MapObjectDynamic o2 = new Spacecraft(new Vector2D(800, 800));
		// final MapObjectDynamic o3 = new Spacecraft(new Vector2D(600, 200));
		final MapObject o4 = new BlackHole(new Vector2D(this.width / 2 - 50,
				this.height / 2 - 50));
		final MapObject o5 = new BlackHole(new Vector2D(1000, 3000));
		final MapObject o6 = new BlackHole(new Vector2D(3000, 1000));
		final MapObject o7 = new BlackHole(new Vector2D(3000, 3000));

		this.map.addMapElement(o1);
		this.map.addMapElement(o2);
		// this.map.addMapElement(o3);
		this.map.addMapElement(o4);
		// this.map.addMapElement(o5);
		// this.map.addMapElement(o6);
		// this.map.addMapElement(o7);

		for (int x = 0; x <= 100; x++) {
			this.map.addTile(new Wall(),
					(int) (Math.random() * (Config.xRes / MapTile.SIZE)),
					(int) (Math.random() * (Config.xRes / MapTile.SIZE)));
		}
		this.map.addTile(new Wall(), 1, 1);
		this.map.addTile(new Wall(), 1, 2);
		this.map.addTile(new Wall(), 1, 3);
		this.map.addTile(new Wall(), 1, 4);

		// new Thread(new Runnable(){
		//
		// @Override
		// public void run() {
		// for (int x = 0; x <= 1000; x++) {
		// map.addMapElement((new Rocket(new Vector2D((int) (Math.random()
		// * map.getWidth() - 1), (int) (Math.random()
		// * map.getHeight() + 1)))));
		// try {
		// Thread.sleep(30);
		// } catch (InterruptedException e) {
		// // TODO Auto-generated catch block
		// e.printStackTrace();
		// }
		// }
		//				 
		// }
		//			
		// }).start();
		//		
		// this.cam1.setHaunted(o1);
		cam1.setHaunted(o2);
		// this.cam3.setHaunted();

		this.cameras.add(cam1);
		// this.cameras.add(cam2);

		this.keyAdabter = new KeyAdapter() {
			private boolean is_w = false;
			private boolean is_up = false;
			private boolean is_enter = false;
			private boolean is_s = false;
			private boolean is_n0 = false;

			@Override
			public void keyPressed(KeyEvent e) {
				int k = e.getKeyCode();
				// System.out.println(k);

				switch (k) {
				case 65:// a
					o1.setAngularRate(-0.1);
					break;
				case 87:// w
					if (is_w == false) {
						o1.getAcceleration().add(
								new Vector2D(1, 0).rotate(o1.getAngle())
										.multiply(1f));
						((Spacecraft) o1)
								.setAccelerationOfAcceleration(new Vector2D(1,
										0).rotate(o1.getAngle()).multiply(0.1));
						is_w = true;
					}
					break;
				case 68:// d
					o1.setAngularRate(0.1);
					break;
				case KeyEvent.VK_LEFT:
					o2.setAngularRate(-0.1);
					break;
				case KeyEvent.VK_UP:// w
					if (is_up == false) {
						o2.getAcceleration().add(
								new Vector2D(1, 0).rotate(o2.getAngle())
										.multiply(1f));
						((Spacecraft) o2)
								.setAccelerationOfAcceleration(new Vector2D(1,
										0).rotate(o2.getAngle()).multiply(0.1));
						is_up = true;
					}
					break;
				case KeyEvent.VK_RIGHT:// d
					o2.setAngularRate(0.1);
					break;
				case KeyEvent.VK_ENTER:// d
					if (is_enter == false) {
						MapObjectDynamic p = new Rocket(o2.getCenterPosition()
								.clone().add(
										new Vector2D(1, 0)
												.rotate(o2.getAngle())
												.contractTo(30)));
						p.setSpeed(new Vector2D(1, 0).rotate(o2.getAngle())
								.multiply(30).add(o2.getSpeed()));
						map.addMapElement(p);
						is_enter = true;
					}
					break;
				case KeyEvent.VK_NUMPAD0:// d
					if (is_n0 == false) {
						MapObjectDynamic p = new Laser(o2.getCenterPosition()
								.clone().add(
										new Vector2D(1, 0)
												.rotate(o2.getAngle())
												.contractTo(30)));
						p.setSpeed(new Vector2D(1, 0).rotate(o2.getAngle())
								.multiply(50).add(o2.getSpeed()));
						map.addMapElement(p);
						is_n0 = true;
					}
					break;
				case KeyEvent.VK_S:// d
					if (is_s == false) {
						MapObjectDynamic p = new Rocket(o1.getCenterPosition()
								.clone().add(
										new Vector2D(1, 0)
												.rotate(o1.getAngle())
												.contractTo(30)));
						p.setSpeed(new Vector2D(1, 0).rotate(o1.getAngle())
								.multiply(30).add(o1.getSpeed()));
						map.addMapElement(p);
						is_s = true;
					}
					break;
				case KeyEvent.VK_ESCAPE:
					System.exit(0);

				}

			}

			@Override
			public void keyReleased(KeyEvent e) {
				int k = e.getKeyCode();
				// System.out.println(k);

				switch (k) {
				case 65:// a
					o1.setAngularRate(0);
					break;
				case 87:// w
					o1.getAcceleration().x = 0;
					o1.getAcceleration().y = 0;
					is_w = false;
					((Spacecraft) o1)
							.setAccelerationOfAcceleration(new Vector2D());
					break;
				case 68:// d
					o1.setAngularRate(0);
					break;
				case KeyEvent.VK_LEFT:
					o2.setAngularRate(0);
					break;
				case KeyEvent.VK_UP:// w
					o2.getAcceleration().x = 0;
					o2.getAcceleration().y = 0;
					is_up = false;
					((Spacecraft) o2)
							.setAccelerationOfAcceleration(new Vector2D());
					break;
				case KeyEvent.VK_RIGHT:// d
					o2.setAngularRate(0);
					break;
				case KeyEvent.VK_ENTER:
					is_enter = false;
					break;
				case KeyEvent.VK_NUMPAD0:
					is_n0 = false;
					break;
				case KeyEvent.VK_S:
					is_s = false;
					break;

				}
			}
		};

	}

	@Override
	public void tick() {
		map.tick();

		for (Camera c : this.cameras)
			c.tick();

	}

	@Override
	public void draw(Graphics2D g2) {
		for (Camera c : this.cameras)
			c.draw(g2);

		g2.setColor(Color.GRAY);
		g2.drawString("Objects: " + this.map.getNumberOfObjects(), 100, 20);
		g2.drawString("Checked collisions: " + this.map.collisionCounter, 180,
				20);
	}
}
